package exebuilder.controller;

import exebuilder.core.Controllers;
import exebuilder.core.Windows;
import exebuilder.data.JdkDownloadConfig;
import exebuilder.ui.ExeBuilderWindow;
import javafx.application.Platform;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.ResourceBundle;

public class DownloadJdkProcessController implements Initializable {

  private static final Logger logger = LogManager.getLogger();
  public ProgressBar downloadJdkProgressBar;
  public Label downloadProcessLabel;
  public Button cancelButton;
  public Label speedLabel;
  double countLen = 0;
  double ratio = 0;
  Thread downloadJdkThread;
  ExeBuilderWindow downloadJdkProcessWindow = Windows.get("downloadJdkProcess");
  JdkDownloadConfig jdkDownloadConfig = JdkDownloadConfig.getInstance();

  public void downloadJdk(String urlPath, String targetDirectory) throws IOException {
    var df = new DecimalFormat("0.00");
    var url = new URL(urlPath);
    var http = (HttpURLConnection) url.openConnection();
    http.setConnectTimeout(3000);
    http.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");
    var length = http.getContentLengthLong();
    logger.info("JDK文件大小：" + (length / 1024) + "KB");
    var fileName = getFileName(http, urlPath);
    var inputStream = http.getInputStream();
    byte[] buff = new byte[1024 * 1024 * 50];
    File destFile = new File(targetDirectory, fileName);
    if (destFile.exists()) {
      destFile.delete();
    }
    var out = new FileOutputStream(destFile);
    int len;
    logger.info("开始下载...");
    var startTime = System.currentTimeMillis();
    while ((len = inputStream.read(buff)) != -1) {
      if (downloadJdkThread.isInterrupted()) {
        logger.info("下载中断");
        break;
      }
      var currentTime = System.currentTimeMillis();
      var timeDiff = (currentTime - startTime) / 1000;
      out.write(buff, 0, len);
      out.flush();
      countLen += len;
      var value = timeDiff == 0 ? 0 : (countLen / timeDiff) / 1024;
      ratio = countLen / length;
      Platform.runLater(() -> {
        downloadJdkProgressBar.setProgress(ratio);
        downloadProcessLabel.setText(df.format(ratio * 100) + "%");
        if (value > 1024) {
          speedLabel.setText(df.format(value / 1024) + "MB/s");
        } else {
          speedLabel.setText(df.format(value) + "KB/s");
        }
      });
    }
    out.close();
    inputStream.close();
  }

  private static String getFileName(HttpURLConnection http, String urlPath) {
    String headerField = http.getHeaderField("Content-Disposition");
    String fileName = null;
    if (null != headerField) {
      String decode = URLDecoder.decode(headerField, StandardCharsets.UTF_8);
      fileName = decode.split(";")[1].split("=")[1].replaceAll("\"", "");
      logger.info("JDK文件名： " + fileName);
    }
    if (null == fileName) {
      String[] arr = urlPath.split("/");
      fileName = arr[arr.length - 1];
      logger.info("url中获取JDK文件名：" + fileName);
    }
    return fileName;
  }

  public void cancelDownload() {
    downloadJdkThread.interrupt();
    downloadJdkProcessWindow.close();
  }

  @Override
  public void initialize(URL url, ResourceBundle resourceBundle) {
    Controllers.add("downloadJdkProcess", this);
    downloadJdkProcessWindow.setOnCloseRequest(windowEvent -> cancelDownload());
    downloadJdkThread = new Thread(() -> {
      try {
        downloadJdk(jdkDownloadConfig.getUrl(), jdkDownloadConfig.getOutputPath());
        logger.info("JDK下载完毕");
        Platform.runLater(() -> speedLabel.setText("下载完毕"));
      } catch (IOException e) {
        e.printStackTrace();
      }
    });
    downloadJdkThread.start();
  }
}
